<template>
  <div class="tree">
    <!-- 递归渲染节点 -->
    <TreeNode v-for="(node, index) in treeData" :key="node.id" :node="node" />  
  </div>
</template>
<script setup>
import TreeNode from "./tree-node.vue";
import { reactive, onMounted, onUnmounted } from "vue";
import bus from "./bus.js"; // 导入事件总线
// 将 treeData 包装为响应式对象
const props = defineProps({
  treeData: {
    type: Array,
    required: true,
  },
});
const treeData = reactive([...props.treeData]); // 确保 treeData 是响应式的

// 递归设置 parent（初始化时调用）
const setParentReference = (nodes, parent = null) => {
  nodes.forEach((node) => {
    node.parent = parent;
    if (node.children) {
      setParentReference(node.children, node);
    }
  });
};
// 初始化时设置 parent 属性
setParentReference(treeData);

const handleVisibilityChange = ({ node, visible }) => {
  node.visible = visible;
  updateParentVisibility(node); // 更新父节点状态
  updateChildrenVisibility(node, visible); // 更新子节点状态
};
const handleExpandChange = ({ node, expanded }) => {
  node.expanded = expanded;
};

// 组件挂载时添加事件监听器，销毁时移除监听器
onMounted(() => {
  bus.on("toggle-visibility", handleVisibilityChange);
  bus.on("update-expanded", handleExpandChange);
});
onUnmounted(() => {
  bus.off("toggle-visibility", handleVisibilityChange);
  bus.off("update-expanded", handleExpandChange);
});

// 递归更新父节点的可见状态
const updateParentVisibility = (node) => {
  if (node.parent) {
    const allVisible = node.parent.children.every(
      (child) => child.visible === true
    );
    const allHidden = node.parent.children.every(
      (child) => child.visible === false
    );
    if (allVisible) {
      node.parent.visible = true;
    } else if (allHidden) {
      node.parent.visible = false;
    } else {
      node.parent.visible = null; // 中间状态
    }
    updateParentVisibility(node.parent); // 递归向上更新父节点
  }
};
// 递归更新子节点的可见状态
const updateChildrenVisibility = (node, visible) => {
  if (node.children && node.children.length > 0) {
    node.children.forEach((child) => {
      child.visible = visible;
      updateChildrenVisibility(child, visible); // 递归向下更新子节点
    });
  }
};
</script>
​
<style scoped>
.tree {
   padding-left: 10px;
}
</style>
